package com.misty.admin.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.event.AnalysisEventListener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.misty.admin.service.BlogService;
import com.misty.api.listener.BlogExcelListener;
import com.misty.api.param.file.FileParam;
import com.misty.api.vo.BlogExcelVo;
import com.misty.common.bean.Result;
import com.misty.common.constants.ResultEnum;
import com.misty.dao.domain.Blog;
import com.misty.dao.dto.BlogDto;
import com.misty.dao.mapper.BlogMapper;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author cthulhu
 * @since 2022-11-21
 */
@Service
public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog> implements BlogService {

    @Resource
    private BlogMapper blogMapper;

    /**
     *
     * @Param
     * @return
     * @Description 新增博客
     * @Date
     **/
    @Override
    public Result<?> saveBlog(Blog blog) {
        if(blog.getUserId() == null){
            blog.setUserId(3); //admin
        }
        blog.setCreateTime(LocalDateTime.now());
        blog.setUpdateTime(LocalDateTime.now());
        int insert = blogMapper.insert(blog);
        if(insert <= 0){
            Result.error(ResultEnum.FAILURE.getValue(),"新增博客失败！");
        }
        return Result.success(ResultEnum.SUCCESS.getValue(),"新增博客成功！");
    }

    /**
     *
     * @Param
     * @return
     * @Description 更新博客
     * @Date
     **/
    @Override
    public Result<?> updateBlog(Blog blog) {
        blog.setUpdateTime(LocalDateTime.now());
        int updateById = blogMapper.updateById(blog);
        if(updateById <= 0){
            Result.error(ResultEnum.FAILURE.getValue(),"更新博客失败！");
        }
        return Result.success(ResultEnum.SUCCESS.getValue(),"更新博客成功！");
    }


    /**
     *
     * @Param
     * @return
     * @Description 删除博客
     * @Date
     **/
    @Override
    public Result<?> deleteBlog(Integer blogId) {
        int deleteById = blogMapper.deleteById(blogId);
        if(deleteById <= 0){
            Result.error(ResultEnum.FAILURE.getValue(),"删除博客失败！");
        }
        return Result.success(ResultEnum.SUCCESS.getValue(),"删除博客成功！");
    }

    /**
     *
     * @Param
     * @return
     * @Description 分页查询博客
     * @Date
     **/
    @Override
    public Result<?> Page(Integer pageNum, Integer pageSize, String search
    ) {
        LambdaQueryWrapper<Blog> blogLambdaQueryWrapper = Wrappers.<Blog>lambdaQuery();
        if(StrUtil.isNotBlank(search)){
            blogLambdaQueryWrapper.like( Blog::getTitle, search);
        }
        Page<BlogDto> blogPage =  blogMapper.selectPageWithUser(new Page<>(pageNum, pageSize), blogLambdaQueryWrapper);
        if(blogPage.getTotal() <= 0){
            Result.error(ResultEnum.FAILURE.getValue(),"分页查询博客失败！");
        }
        return Result.success(ResultEnum.SUCCESS.getValue(),"分页查询博客成功！",blogPage);
    }

    /**
     *
     * @Param
     * @return
     * @Description 查询所有博客
     * @Date
     **/
    @Override
    public Result<List<BlogDto>> getAllInfo() {
        QueryWrapper<BlogDto> queryWrapper = new QueryWrapper<>();
        List<BlogDto> blogDtos = blogMapper.selectPageWithUser(queryWrapper);
        if(CollUtil.isEmpty(blogDtos)){
            return Result.error("查询所有博客成功！");
        }
        return Result.success("分页查询博客成功！",blogDtos);
    }

    /**
     *
     * @Param
     * @return
     * @Description 查询博客排行
     * @Date
     **/
    @Override
    public Result<?> order(Integer pageNum, Integer pageSize, String search
    ) {
        QueryWrapper<Blog> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByAsc("views")
                .like("title",search);
        Page<BlogDto>  blogPage =  blogMapper.selectByOrder(new Page<>(pageNum, pageSize), queryWrapper);
        if(blogPage.getTotal() <= 0){
            Result.error("查询博客排行失败！");
        }
        return Result.success("查询博客排行成功！");
    }

    /**
     *
     * @Param
     * @return
     * @Description 查询该博客内容与用户信息
     * @Date
     **/
    @Override
    public Result<?> selectByIdWithUser(Integer id){
        QueryWrapper<Blog> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("blog.id",id);
        BlogDto blog = blogMapper.selectByIdWithUser(queryWrapper);
        if(ObjectUtil.isEmpty(blog)){
            Result.error(ResultEnum.FAILURE.getValue(),"查询该博客内容与用户信息失败！");
        }
        return Result.success(ResultEnum.SUCCESS.getValue(),"查询该博客内容与用户信息成功！");
    }

    @Override
    public Result<Map> statistics() {
        //获取今年的年数
        int year = LocalDateTime.now().getYear();

        //存储数据
//        List<Map> countList = new ArrayList<>();
        Map<String,Map> countMap = new HashMap<>();
        Map<Integer, Integer> blogCount = new HashMap<>();
        Map<Integer, Integer> viewCount = new HashMap<>();
//        HashMap<Integer, Integer> commentCount = new HashMap<>();

        QueryWrapper<Blog> queryWrapper;
        for (int i =1; i <= 12; i++){
            String month = "";
            if(i < 10){
                month = "0" + i;
            }else {
                month = String.valueOf(i);
            }
            queryWrapper  = new QueryWrapper<>();
            queryWrapper  = new QueryWrapper<>();queryWrapper.eq("DATE_FORMAT (create_time,'%Y-%m')",year + "-" + month);
            Long blogMonthCount = blogMapper.selectCount(queryWrapper);
            blogCount.put(i, Math.toIntExact(blogMonthCount));

//            queryWrapper.select("sum(views) as viewsSum");
            List<Blog> blogs = blogMapper.selectList(queryWrapper);
            int sum = blogs.stream()
                    .mapToInt((blog) -> blog.getViews())
                    .sum();
            viewCount.put(i, Math.toIntExact(sum));
        }
        countMap.put("blogCount",blogCount);
        countMap.put("viewCount",viewCount);
        return Result.success("统计成功！",countMap);
    }


    @Override
    public Boolean uploadExcel(FileParam fileParam) throws IOException {
        MultipartFile file = fileParam.getFile();
        AnalysisEventListener<BlogExcelVo> listener = new BlogExcelListener<>(this.batchInsert());
        EasyExcel.read(file.getInputStream(), BlogExcelVo.class, listener).sheet().doRead();
        return true;
    }

    //动态写法
    private Consumer<List<BlogExcelVo>> batchInsert() {
        //其他业务逻辑只需要添加到该方法中即可
        return this::saveData;
    }


    private void saveData(List<BlogExcelVo> list) {
        for (BlogExcelVo consumableExcelVo : list) {
            Blog blog = new Blog();
            blog.setTitle(consumableExcelVo.getTitle());
            blog.setContent(consumableExcelVo.getContent());
            blog.setFirstPicture(consumableExcelVo.getFirstPicture());
            blog.setFlag(consumableExcelVo.getFlag());
            blog.setAppreciation(consumableExcelVo.getAppreciation());
            blog.setShareStatement(consumableExcelVo.getShareStatement());
            blog.setCommentabled(consumableExcelVo.getCommentabled());
            blog.setPublished(consumableExcelVo.getPublished());
            blog.setRecommend(consumableExcelVo.getRecommend());
            blog.setUserId(consumableExcelVo.getUserId());
            this.saveBlog(blog);
        }
    }

}
